C++에서는 대부분의 연산자를 오버로딩할 수 있다.
하지만, 일부 연산자는 특정 목적을 위해서만 오버로드하는 것이 좋다.
일관성있게 디자인오버로딩에서 특정 애플리케이션 도메인에서의 동작을 간결하게 표현하기 위해,
도메인 특정 임베디드 언어(Domain-Specific Embedded Languages, DSEL)을 확립하는데 사용
DSEL은 그 자체로 일관성이 있어야 한다.
연산자는 서로 일관되게 정의하고 필요할 때마다 표준 타입과 유사한 의미를 제공할 것
연산자를 재정의할 때, 자유롭게 재정의 가능하지만, 연산자의 측면 항(Arity)는 미리 정의되어 있다.
ex)
곱셈은 항상 두개의 인수를 취함, 일부는 가변적인 항을 취한다(첨자 연산자)
응용연산자인 operator()만이 임의의 항을 허용한다
우선순위를 존중하라연산자를 재정의할 때 연산의 예상 우선순위가 일치하는지 확인해야 한다.
오버로드한 연산자의 의미 / 의도한 우선순위가 C++ 연산자의 우선순위와 일치해야 한다.
멤버 함수 또는 자유 함수대부분의 연산자는 멤버 함수 또는 자유 함수로 정의할 수 있다.
모든 종류의 할당 연산자, operator[], operator->, operator()는 첫 번째 인수가 Lvalue인지 확인하기 위해
비정적 메서드를 사용해야 한다. 반대로 첫 번째 인수가 내장 타입을 갖는 이진 연산자는 자유 함수로만 정의할
수 있다.
class complex{
public:
explicit complex(double rn=0.0, double in=0.0):r(rn), i(in){}
complex operator+(const complex& c2) const{
return complex(r+c2.r, i+c2.i);
}
private:
double r, i;
};
int main(void){
complex cc(7.0, 8.0), c4(cc);
std::cout<<"cc+c4 is "<<cc+c4<<std::endl;
}
complex 인스턴스에 double을 더하기 위해서는 explicit를 사용하지 않거나, double을 허용하는 오버로드를
추가해 주어야 한다.
class complex{
complex operator+(double r2) const{
return complex(r+r2, i);
}
};
int main(void){
complex cc(7.0, 8.0);
std::cout<<"4.2+cc is "<<4.2+cc<<std::endl;
}
하지만 인수의 순서가 바뀔 경우 위 코드는 컴파일 되지 않는다.
순서를 바뀌어서 연산을 처리하기 위해서는 자유 함수 작성을 필요로 한다.
inline complex operator+(double d, const complex& c2){
return complex(d+real(c2), imag(c2));
}
inline complex operator+(const complex& c1, const complex& c2){
return complex(real(c1)+real(c2), imag(c1)+imag(c2));
}
멤버함수 & 자유함수멤버함수의 경우, 두 번째 인수에 대한 암시적 변환만 허용하지만
자유함수는 두 인수 모두 암시적 변환을 허용한다.
단항 연산자
complex operator-(const complex& c1){
return complex(-real(c1), -imag(c1));
}
class complex{
public:
complex operator-() const{
return complex(-r, -i);
};
스트림 출력 연산자
std::ostream& operator<<(std::ostream& os, const complex& c){
return os << '(' << real(c) << ',' << imag(c) << ')';
}